#include "stdafx.h"
#include "Processor.h"
#include "CXSegment.h"
#include <MyControls/AsyncCall.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

void ProcessQueue::Clear()
{
	DequeType::iterator i;
	for (i = m_Queue.begin(); i != m_Queue.end(); ++i) {
		(*i)->OnProcessingFinish();
	}
	superclass::Clear();
}

void ProcessQueue::Remove(CXSegment * pSegm)
{
	DequeType::iterator i = std::find(m_Queue.begin(), m_Queue.end(), pSegm);
	if (i != m_Queue.end()) {
		(*i)->OnProcessingFinish();
		m_Queue.erase(i);
	}
	//for segment whose processing was begun status change will occur in Execute()
}

Processor::Processor()
{
	//resume() should be the last command in thread construction sequence
	SetThreadPriority(handle(), THREAD_PRIORITY_BELOW_NORMAL);
	resume();
}

Processor::~Processor()
{
	//thread should terminate before destruction will take place
	Terminate();
	wait_finish();
}

void Processor::report_error(const char * msg)
{
	AfxMessageBox(msg, MB_OK | MB_ICONEXCLAMATION);
}

class TidySegment {
public:
	TidySegment(CXSegment & s) : m_Segment(s) { }
	~TidySegment() {
		AsyncCall(m_Segment, &CXSegment::OnProcessingFinish);
	}
private:
	CXSegment & m_Segment;
};

void Processor::Execute(const ProcessOrder & pSegm)
{
	mswin::thread::set_debug_name("Processor");

	CXSegment & s = *pSegm;
	TidySegment tidy_on_return(s);
	SegmentData & d = s.Data();
	try {
		d.calc(false, s.GetTimeSpan());
	}
	catch (...) {
		Cancel(); //cancel processing of other segments if any waiting
		throw;
	}
}
